---
title: Application tech debt
summary: Security, correctness and maintenance findings for NDReimbursementWebApp, with severity, impact and recommendation.
status: generated
owner: SAIF Case Management
last_reviewed: 2026-10-20
---

# Application tech debt

This register lists 14 findings: 3 high, 7 medium, 3 low and 1 informational. There are no critical findings. Findings whose impact depends on API behavior that could not be traced are marked **.

## Findings summary

| ID | Severity | Title |
| --- | --- | --- |
| TD-APP-001 | HIGH | Anti-forgery validation disabled on all POST handlers |
| TD-APP-002 | HIGH | Developer-access handler escalates capability flags |
| TD-APP-003 | HIGH | No server-side role check on state-changing handlers |
| TD-APP-004 | MEDIUM | `CanPrint` is computed but never enforced |
| TD-APP-005 | MEDIUM | Audit user name is client-supplied |
| TD-APP-006 | MEDIUM | Pay-online maximum and policy number are client-supplied |
| TD-APP-007 | MEDIUM | Delete confirmation form lacks a POST method |
| TD-APP-008 | MEDIUM | Unvalidated date parsing and server-side window not enforced |
| TD-APP-009 | MEDIUM | Pay by mail and download statement drop the last PDF byte |
| TD-APP-010 | MEDIUM | Sync-over-async call in the page model constructor |
| TD-APP-011 | LOW | Development environment, permissive CORS and disabled SSL setting |
| TD-APP-012 | LOW | No model validation |
| TD-APP-013 | LOW | Dead and orphaned code |
| TD-APP-014 | INFO | Package versions lag the feed |

## TD-APP-001

Severity HIGH. `[IgnoreAntiforgeryToken]` on the page model, and on `BolMenuModel` †, disables anti-forgery validation for all 12 POST handlers, eight of them state-changing ([BR-APP-006](business-rules.md#br-app-006)). Impact: cross-site request forgery can update claims, override due dates, delete statements and create payment requests using the victim's Windows credentials. Recommendation: remove the attribute and send the anti-forgery token from `ClaimsTable.js` and `PaymentModal.js` in a `RequestVerificationToken` header. Raise the base-class behavior with the BolMiddleware owners. Evidence: `Pages/NDReimbursement.cshtml.cs` line 10, `ClaimsTable.js` line 233, `PaymentModal.js` line 29.

## TD-APP-002

Severity HIGH. The developer-access handler is routable by direct POST with no IT or QA check, and `PolicyHolder` or `DueDate` forces an updater flag to true ([BR-APP-005](business-rules.md#br-app-005)). Impact: any authorized user, including a read-only user, can escalate to updater capabilities in the UI flags. The effect on updates is limited by the API**, because the other handlers do not check the flags. Recommendation: remove the handler and `DevAccessType`, or restrict it to `IsInternalITUser` with a server-side check and a non-production flag.

## TD-APP-003

Severity HIGH. Override, delete and download rely on the view hiding controls. The due-date and delete handlers check no role, and the update, pay-by-mail and pay-online handlers do not check the updater roles ([BR-APP-003](business-rules.md#br-app-003)). Impact: a read-only or external user can POST to internal-only handlers directly, because the page gate admits all four roles ([BR-APP-001](business-rules.md#br-app-001)). Recommendation: enforce `IsInternalUpdater` or `IsExternalUpdater` in each handler, or use per-handler `SecurityApiAuthorize`, and return 403.

## TD-APP-004

Severity MEDIUM. `CanPrint` (role `DocCoreApiUserResource`) is computed but never enforced on the download handler. Impact: any page-level user can download the statement PDF. Recommendation: check `CanPrint` in the download and pay-by-mail handlers and verify that the statement belongs to the policy in context.

## TD-APP-005

Severity MEDIUM. The audit user (`UpdateUser`) comes from the client-supplied `UserName`. Impact: the audit trail can be forged. Recommendation: use `CurrentUserId` on the server.

## TD-APP-006

Severity MEDIUM. Pay online validates the total against a client-supplied `maxAmount`, and `policyNum` is read from a client-side hidden field ([BR-SCR-007](business-rules.md#br-scr-007)). Impact: the client can bypass the limit or pay against another policy**. Recommendation: recompute the maximum and policy from the server-side statement.

## TD-APP-007

Severity MEDIUM. The delete-confirmation form has no `method="post"`. The form submits GET; the only delete handler is `OnPostDeleteStatement` (no `OnGetDeleteStatement`), so the form cannot invoke it, and a script function that would perform the delete is never called. Impact: deletion cannot be performed from the UI (the HTTP result of the unmatched GET is unspecified**); the handler is reachable only by a separately issued POST. Recommendation: add `method="post"` with a token (see TD-APP-001) and remove the dead script.

## TD-APP-008

Severity MEDIUM. The due-date handler uses `DateTime.Parse` on raw form input with no culture or validation. The 90-day window is not enforced on the server ([BR-SCR-002](business-rules.md#br-scr-002)), and the minimum and maximum override dates are not zero-padded. Impact: wrong dates or exceptions, and out-of-window overrides. Recommendation: use `DateTime.TryParseExact` with an invariant culture and re-check the window on the server.

## TD-APP-009

Severity MEDIUM. Both `OnPostPayByMail` and `OnPostDownloadStatement` write `Preview.Length - 1` bytes to the response, which drops the final byte of the PDF. Impact: the statement PDF returned by either handler may be corrupt or truncated. Recommendation: write the whole buffer (`Preview.Length` bytes) in both handlers and add a test for each.

## TD-APP-010

Severity MEDIUM. The constructor calls `IsAuthorizedAsync` call followed by `.Result`. Impact: thread-pool starvation and deadlock risk. Recommendation: move the call into an async lifecycle hook.

## TD-APP-011

Severity LOW. `web.config` hard-codes `ASPNETCORE_ENVIRONMENT=Development` and permissive CORS headers (`Access-Control-Allow-Credentials: true`, origin `http://localhost`). `appsettings.json` sets `Ssl:Disabled` to "true". No secrets are committed. Impact: development behavior may reach deployed hosts. Recommendation: set the environment per stage in the pipeline, remove the CORS headers and make the SSL setting per environment.

## TD-APP-012

Severity LOW. No handler checks `ModelState` or validates input, and raw form keys are read directly. Impact: malformed input reaches the API. Recommendation: add validation.

## TD-APP-013

Severity LOW. Dead and orphaned code: a duplicate jQuery 3.6.0 from a public CDN, a malformed click binding in `NDReimbursementWebApp.js`, a dead delete script, `ViewDocument.js`, `SaifDropdown.js`, an empty `site.js`, `_ValidationScriptsPartial`, the orphan `_MakePaymentModalBase`, unused `PayOnlineApp` and `PayOnlinePage`, commented-out start-up code, and stale `sass-kendo` and legacy stylesheet build configuration. Impact: maintenance cost and supply-chain exposure. Recommendation: remove the dead code, use one jQuery and pin or self-host scripts. The claim profile link in the view uses a legacy page extension hard-coded to another application.

## TD-APP-014

Severity INFO. BolMiddleware 2.0.25309.3 and four API clients lag the feed (BolMiddleware 2.2026.929.1, DigitalPaymentAPIClient 6.2026.610.1, NDReimbursementAPI.Client 1.2026.413.1). Impact: missing package fixes**, in particular for the cookie risks in [INH-008](business-rules.md#inh-008). Recommendation: plan an upgrade and a regression test.

> **Note:** Statements marked with `†` are derived from dependency library
> documentation via the Legends CLI. Statements marked with `**` could
> not be confirmed; treat as unknown until verified.

## Related documentation
- [Application index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Configuration](configuration.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Security and authorization](security-authorization.md)
- [Data model](data-model.md)
- [Hosted endpoints](hosted-endpoints.md)

## Sources
- src/NDReimbursementWebApp/Pages/NDReimbursement.cshtml.cs
- src/NDReimbursementWebApp/Pages/NDReimbursement.cshtml
- src/NDReimbursementWebApp/wwwroot/js/ClaimsTable.js
- src/NDReimbursementWebApp/wwwroot/js/PaymentModal.js
- src/NDReimbursementWebApp/wwwroot/js/NDReimbursementWebApp.js
- src/NDReimbursementWebApp/web.config
- src/NDReimbursementWebApp/appsettings.json
- src/NDReimbursementWebApp/NDReimbursementWebApp.csproj
